package com.infitecs.eyas;

import com.infitecs.eyas.develop.service.MenuService;
import com.infitecs.eyas.power.model.Power;
import com.infitecs.eyas.security.model.User;
import com.infitecs.eyas.security.service.UserService;
import com.infitecs.eyas.session.SessionService;
import com.infitecs.eyas.util.HttpSessionUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
@RequestMapping("/login")
public class LoginController {

    @Autowired
    private MenuService menuService;

    @Autowired
    private UserService userService;

    @Autowired
    private SessionService sessionService;

    @RequestMapping(method = {RequestMethod.GET})
    public String login(HttpSession session) {
        session.setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, new Locale("zh"));
        return "login";
    }

    @RequestMapping("loginError")
    public String power(HttpServletRequest request) {
        return "error/loginError";
    }


    @RequestMapping(method = {RequestMethod.POST})
    public String loginPost(User user, RedirectAttributes redirectAttributes, HttpServletRequest request, HttpServletResponse response) throws IOException, ParseException {
        Subject currentUser = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
        try {
            currentUser.login(token);
        } catch (AuthenticationException e) {
            redirectAttributes.addFlashAttribute("message", "用户名或密码错误");
            return "redirect:/login";
        }
        if (currentUser.isAuthenticated()) {
            sessionHandle(user, request);
            user = userService.getUserByUsername(user.getUsername());
            if (!compareDate(user.getEffectiveDate()) ) {
                redirectAttributes.addFlashAttribute("message", "用户超过有效期");
                return "redirect:/login";
            }

            if (!user.getIp().equals(getIp(request)) && "1".equals(user.getIpFlag())) {
                redirectAttributes.addFlashAttribute("message", "未在设定ip登录");
                return "redirect:/login";
            }
            mulLoginHandle(user, request.getSession());
            return "redirect:" + getSavedUrl(request);
        } else {
            redirectAttributes.addFlashAttribute("message", "用户名或密码错误");
            return "redirect:/login";
        }
    }

    private boolean compareDate(String date) throws ParseException {
        if(date==null||"".equals(date)){
            return true;
        }
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date effecvite = dateFormat.parse(date);
        Date now = new Date();
        return effecvite.getTime() > now.getTime();
    }

    private String getIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    private String getSavedUrl(HttpServletRequest request) {
        SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(request);
        if (savedRequest == null) {
            return "/";
        }
        String savedUrl = savedRequest.getRequestUrl().replace(request.getContextPath(), "");
        if (!savedUrl.contains("menuId")) {
            savedUrl = "/";
        }
        return savedUrl;
    }

    private void sessionHandle(User user, HttpServletRequest request) {
        sessionService.addPowerMap();
        user = userService.getUserByUsername(user.getUsername());
        user.setRoleList(userService.getRolesByUsername(user.getUsername()));
        HttpSessionUtil.saveUserToSession(user, request);
        menuService.updateMenuInHttpSession(request);
    }

    @RequestMapping(value = "/isLogin", method = RequestMethod.GET)
    @ResponseBody
    public boolean isLogin(String loginName, HttpServletRequest request) {
        ServletContext context = request.getSession().getServletContext();
        Map logonUsers = (HashMap) context.getAttribute("logonUsers");
        if (logonUsers == null) {
            logonUsers = new HashMap();
        }
        return logonUsers.containsKey(loginName);
    }

    private void mulLoginHandle(User user, HttpSession session) {
        ServletContext context = session.getServletContext();
        Map logonUsers = (HashMap) context.getAttribute("logonUsers");
        if (logonUsers == null) {
            logonUsers = new HashMap();
        }
        logonUsers.put(user.getUsername(), session.getId());
        context.setAttribute("logonUsers", logonUsers);
    }
}
